
PM_FUNC_NORM_ATTRIB TradeClear( Int:iPlayer, Int:iTradePlayer = 0 )
{
	pokemod_funcstart_debug( "TradeClear" );

	PlayerSetInfo( iPlayer, PINFO_TRADE_PLAYER, iTradePlayer );
	PlayerSetInfo( iPlayer, PINFO_TRADE_POKEMON, 0 );
	PlayerSetInfo( iPlayer, PINFO_TRADE_LEVEL, 0 );
	PlayerSetInfo( iPlayer, PINFO_TRADE_ITEM, -1 );
	PlayerSetInfo( iPlayer, PINFO_TRADE_ITEMNUM, 0 );
	PlayerSetInfo( iPlayer, PINFO_TRADE_MONEY, 0 );
	PlayerSetInfo( iPlayer, PINFO_TRADE_ACCEPT, 0 );

	pokemod_funcend_debug( "TradeClear" );
}

PM_FUNC_NORM_ATTRIB TradeMenu( Int:iPlayer )
{
	pokemod_funcstart_debug( "TradeMenu" );

	new Int:iTradePlayer = PlayerGetInfo( iPlayer, PINFO_TRADE_PLAYER );
	if ( !is_user_connected( iTradePlayer ) )
	{
		new iPlayers[32], iPlayerCount;
		get_players( iPlayers, iPlayerCount, PLAYER_FLAGS_REAL );
		if ( iPlayerCount > 1 )
		{
			TradePlayer( iPlayer );

			pokemod_funcend_debug( "TradeMenu No Player" );
			return;
		}

		iTradePlayer = 0;
	}

	new Int:iMenu = MenuCreate( "Trade Menu" );

	new Int:iPlayerPokemon = PlayerGetInfo( iPlayer, PINFO_TRADE_POKEMON );
	new Int:iPlayerLevel = PlayerGetInfo( iPlayer, PINFO_TRADE_LEVEL );
	new Int:iPlayerItem = PlayerGetInfo( iPlayer, PINFO_TRADE_ITEM );
	new Int:iPlayerItemAmount = PlayerGetInfo( iPlayer, PINFO_TRADE_ITEMNUM );
	new Int:iPlayerMoney = PlayerGetInfo( iPlayer, PINFO_TRADE_MONEY );
	if ( !iPlayerItemAmount )
		iPlayerItem = -1;

	new bool:bTrading = PlayerGetInfo( iTradePlayer, PINFO_TRADE_PLAYER ) == iPlayer;
	new String:szTradeStatus[ 32 ];
	if ( bTrading )
		copy( szTradeStatus, charsmax(szTradeStatus), "\yTrading\w" );
	else
		copy( szTradeStatus, charsmax(szTradeStatus), "\rWaiting...\w" );

	new String:szTradePlayer[ NAME_LEN ];
	PlayerToName( iTradePlayer, szTradePlayer, charsmax(szTradePlayer) );

	if ( iTradePlayer )
	{
		new Int:iTradePokemon = PlayerGetInfo( iTradePlayer, PINFO_TRADE_POKEMON );
		new Int:iTradeLevel = PlayerGetInfo( iTradePlayer, PINFO_TRADE_LEVEL );
		new Int:iTradeItem = PlayerGetInfo( iTradePlayer, PINFO_TRADE_ITEM );
		new Int:iTradeItemAmount = PlayerGetInfo( iTradePlayer, PINFO_TRADE_ITEMNUM );
		new Int:iTradeMoney = PlayerGetInfo( iTradePlayer, PINFO_TRADE_MONEY );
		if ( !iTradeItemAmount )
			iTradeItem = -1;

		MenuAddItem( iMenu, "player", "Player: %s (%s)^nPokemon: %s (Lvl %d)^nItem: %s x %d^n$%d", szTradePlayer, szTradeStatus, PokeToName( iTradePokemon ), iTradeLevel, ItemToName( iTradeItem ), iTradeItemAmount, iTradeMoney );
	}
	else
		MenuAddItem( iMenu, "player", "Select a Player to Trade" );

	MenuAddText( iMenu, "^n\yYou are trading:" );
	MenuAddItem( iMenu, "poke", "Pokemon: %s (Lvl %d)", PokeToName( iPlayerPokemon ), iPlayerLevel );
	MenuAddItem( iMenu, "item", "Item: %s x %d", ItemToName( iPlayerItem ), iPlayerItemAmount );
	MenuAddItem( iMenu, "money", "$%d", iPlayerMoney );

	if ( iTradePlayer && bTrading )
	{
		if ( PlayerGetInfo( iPlayer, PINFO_TRADE_ACCEPT ) )
		{
			MenuAddText( iMenu, "\yTrade Accepted" );
			MenuAddItem( iMenu, "accept", "Edit Trade");
		}
		else
			MenuAddItem( iMenu, "accept", "Accept Trade");

		if ( PlayerGetInfo( iTradePlayer, PINFO_TRADE_ACCEPT ) )
			MenuAddText( iMenu, "%s Accepted", szTradePlayer );
		else
			MenuAddText( iMenu, "Waiting on %s", szTradePlayer );
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true );

	MenuDisplay( iPlayer, iMenu, MENU_TRADE );

	pokemod_funcend_debug( "TradeMenu" );
}

PM_FUNC_NORM_ATTRIB TradePlayer( Int:iPlayer )
{
	pokemod_funcstart_debug( "TradePlayer" );

	new Int:iMenu = MenuCreate( "Trade Menu" );
	new String:szData[32];

	new Int:iTradePlayer;
	new Int:iColorChar;

	LoopThroughPlayersFlags( iPlayerID, PLAYER_FLAGS_REAL )
	{
		if ( iPlayer == iPlayerID )
			continue;

		iTradePlayer = PlayerGetInfo( iPlayerID, PINFO_TRADE_PLAYER );
		if ( iTradePlayer == iPlayer )
			iColorChar = 'y';
		else if ( !iTradePlayer )
			iColorChar = 'w';
		else
			iColorChar = 'd';

		formatex( szData, charsmax(szData), "player%d", iPlayerID );
		MenuAddItem( iMenu, szData, "\%c%s", iColorChar, PlayerToName( iPlayerID ) );
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true );

	MenuDisplay( iPlayer, iMenu, MENU_TRADE_SUB );

	pokemod_funcend_debug( "TradePlayer" );
}

PM_FUNC_NORM_ATTRIB TradePokemon( Int:iPlayer )
{
	pokemod_funcstart_debug( "TradePokemon" );

	new Int:iActivePokeNum = PlayerGetInfo( iPlayer, PINFO_ACTIVE_POKENUM );
	new Int:iCurrentTradePoke = PlayerGetInfo( iPlayer, PINFO_TRADE_POKEMON );

	new Int:iMenu = MenuCreate( "Trade Pokemon Menu (%s)", PokeToName( iCurrentTradePoke ) );
	new String:szData[32];

	new Int:iPokemon, Int:iLevel;
	new Int:iColorChar;

	for ( new Int:iPokeNum; iPokeNum < POKEMON_PER_PLAYER; iPokeNum++ )
	{
		iPokemon = g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_POKEMON ];
		if ( iPokemon <= 0 )
			continue;

		iLevel = g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_LEVEL ];

		if ( iActivePokeNum == iPokeNum )
			iColorChar = 'd';
		else if ( iCurrentTradePoke == iPokemon )
			iColorChar = 'y';
		else
			iColorChar = 'w';

		formatex( szData, charsmax(szData), "poke%d", iPokemon );
		MenuAddItem( iMenu, szData, "\%c%s (Lvl %d)", iColorChar, PokeToName( iPokemon ), iLevel );
	}

	if ( iCurrentTradePoke <= 0 )
		iColorChar = 'y';
	else
		iColorChar = 'w';

	formatex( szData, charsmax(szData), "poke0" );
	MenuAddItem( iMenu, szData, "\%cNone", iColorChar );

	MenuExit( iPlayer, iMenu, .bExitOption = true, .szExitName = "Back to Trade" );

	MenuDisplay( iPlayer, iMenu, MENU_TRADE_SUB );

	pokemod_funcend_debug( "TradePokemon" );
}

PM_FUNC_NORM_ATTRIB TradeItem( Int:iPlayer )
{
	pokemod_funcstart_debug( "TradeItem" );

	new Int:iCurrentTradeItem = PlayerGetInfo( iPlayer, PINFO_TRADE_ITEM );

	new Int:iMenu = MenuCreate( "Trade Item Menu (%s)", ItemToName( iCurrentTradeItem ) );
	new String:szData[32];

	if ( iCurrentTradeItem != -1 )
	{
		new Int:iItemAmount = PlayerGetInfo( iPlayer, PINFO_TRADE_ITEMNUM );
		formatex( szData, charsmax(szData), "inum" );
		MenuAddItem( iMenu, szData, "\y%s x %d", ItemToName( iCurrentTradeItem ), iItemAmount );
	}

	new Int:iColorChar;
	if ( iCurrentTradeItem == -1 )
		iColorChar = 'y';
	else
		iColorChar = 'w';

	MenuAddItem( iMenu, "item-1", "\%cNone", iColorChar );

	new Array:iPlayerItems = g_iPlayerItems[ iPlayer ];
	new Int:iSize = ArraySize( iPlayerItems ) / _:PLAYER_ITEM;
	if ( iSize )
	{
		for ( new Int:iItemID, Int:iItemNum, Int:iProp;
			iItemNum < iSize;
			iItemNum++
		){
			iItemID = ArrayGetCell( iPlayerItems, ( ( iItemNum * _:PLAYER_ITEM ) + _:ITEM_ID ) );

			if ( iCurrentTradeItem == iItemID )
				continue;

			iProp = ArrayGetCell( g_iItemProps, iItemID );
			if ( iProp & ( 1 << _:ITEM_UNTRADABLE ) )
				continue;

			formatex( szData, charsmax(szData), "item%d", iItemID );
			MenuAddItem( iMenu, szData, "%s", ItemToName( iItemID ) );
		}
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true, .szExitName = "Back to Trade" );

	MenuDisplay( iPlayer, iMenu, MENU_TRADE_SUB );

	pokemod_funcend_debug( "TradeItem" );
}

PM_FUNC_NORM_ATTRIB TradeItemAmount( Int:iPlayer )
{
	pokemod_funcstart_debug( "TradeItemAmount" );

	new Int:iTradeItem = PlayerGetInfo( iPlayer, PINFO_TRADE_ITEM );
	new Int:iTradeAmount = PlayerGetInfo( iPlayer, PINFO_TRADE_ITEMNUM );

	new Int:iMenu = MenuCreate( "Trade Item Menu (%s x %d)", ItemToName( iTradeItem ), iTradeAmount );
	new String:szData[32];

	new Int:iItemAmount;
	new Array:iPlayerItems = g_iPlayerItems[ iPlayer ];
	new Int:iSize = ArraySize( iPlayerItems ) / _:PLAYER_ITEM;
	if ( iSize )
	{
		for ( new Int:iItemID, Int:iItemNum;
			iItemNum < iSize;
			iItemNum++
		){
			iItemID = ArrayGetCell( iPlayerItems, ( ( iItemNum * _:PLAYER_ITEM ) + _:ITEM_ID ) );

			if ( iTradeItem == iItemID )
			{
				iItemAmount = ArrayGetCell( iPlayerItems, ( ( iItemNum * _:PLAYER_ITEM ) + _:ITEM_AMOUNT ) );
			}
		}
	}

	new const String:szDataFormat[] = "inum%d";

	formatex( szData, charsmax(szData), szDataFormat, iTradeAmount );
	MenuAddItem( iMenu, szData, "\y%d", iTradeAmount );

	if ( iItemAmount )
	{
		new Int:iIncreaseAmount = max( 10, ReduceNumber( iItemAmount / 10 ) );
		new Int:iTempAmount = iTradeAmount + iIncreaseAmount;
		if ( iTempAmount <= iItemAmount )
		{
			formatex( szData, charsmax(szData), szDataFormat, iTempAmount );
			MenuAddItem( iMenu, szData, "+%d (%d)", iIncreaseAmount, iTempAmount );
		}
		iTempAmount = iTradeAmount - iIncreaseAmount;
		if ( iTempAmount > 0 )
		{
			formatex( szData, charsmax(szData), szDataFormat, iTempAmount );
			MenuAddItem( iMenu, szData, "-%d (%d)", iIncreaseAmount, iTempAmount );
		}

		iIncreaseAmount = max( 1, ReduceNumber( iItemAmount / 100 ) );
		iTempAmount = iTradeAmount + iIncreaseAmount;
		if ( iTempAmount <= iItemAmount )
		{
			formatex( szData, charsmax(szData), szDataFormat, iTempAmount );
			MenuAddItem( iMenu, szData, "+%d (%d)", iIncreaseAmount, iTempAmount );
		}
		iTempAmount = iTradeAmount - iIncreaseAmount;
		if ( iTempAmount > 0 )
		{
			formatex( szData, charsmax(szData), szDataFormat, iTempAmount );
			MenuAddItem( iMenu, szData, "-%d (%d)", iIncreaseAmount, iTempAmount );
		}

		if ( iTradeAmount != iItemAmount )
		{
			formatex( szData, charsmax(szData), szDataFormat, iItemAmount );
			MenuAddItem( iMenu, szData, "%d", iItemAmount );
		}
	}
	if ( iTradeAmount )
	{
		MenuAddItem( iMenu, "inum0", "0" );
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true, .szExitName = "Back to Trade" );

	MenuDisplay( iPlayer, iMenu, MENU_TRADE_SUB );

	pokemod_funcend_debug( "TradeItemAmount" );
}

PM_FUNC_NORM_ATTRIB TradeMoney( Int:iPlayer )
{
	pokemod_funcstart_debug( "TradeMoney" );

	new Int:iTradeMoney = PlayerGetInfo( iPlayer, PINFO_TRADE_MONEY );
	new Int:iMenu = MenuCreate( "Trade Menu ($%d)", iTradeMoney );
	new String:szData[32];

	new Int:iMoney = PlayerGetMoney( iPlayer );
	if ( iMoney )
	{
		new Int:iTempMoney = iTradeMoney + 100;
		if ( iTempMoney <= iMoney )
		{
			formatex( szData, charsmax(szData), "money%d", iTempMoney );
			MenuAddItem( iMenu, szData, "+$%d ($%d)", 100, iTempMoney );
		}
		iTempMoney = iTradeMoney - 100;
		if ( iTempMoney >= 0 )
		{
			formatex( szData, charsmax(szData), "money%d", iTempMoney );
			MenuAddItem( iMenu, szData, "-$%d ($%d)", 100, iTempMoney );
		}

		iTempMoney = iTradeMoney + 1000;
		if ( iTempMoney <= iMoney )
		{
			formatex( szData, charsmax(szData), "money%d", iTempMoney );
			MenuAddItem( iMenu, szData, "+$%d ($%d)", 1000, iTempMoney );
		}
		iTempMoney = iTradeMoney - 1000;
		if ( iTempMoney >= 0 )
		{
			formatex( szData, charsmax(szData), "money%d", iTempMoney );
			MenuAddItem( iMenu, szData, "-$%d ($%d)", 1000, iTempMoney );
		}

		if ( iTradeMoney != iMoney )
		{
			formatex( szData, charsmax(szData), "money%d", iMoney );
			MenuAddItem( iMenu, szData, "$%d", iMoney );
		}
	}

	if ( iTradeMoney )
	{
		MenuAddItem( iMenu, "money0", "$0" );
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true, .szExitName = "Back to Trade" );

	MenuDisplay( iPlayer, iMenu, MENU_TRADE_SUB );

	pokemod_funcend_debug( "TradeMoney" );
}

PM_FUNC_NORM_ATTRIB TradeComplete( Int:iPlayer, Int:iTradePlayer )
{
	pokemod_funcstart_debug( "TradeComplete" );

	new bool:bTradeFailed = false;

	new Int:iPlayerTrades;
	new String:szTrades[ 3 ][ 32 ];

	new Int:iPlayerPokemon = PlayerGetInfo( iPlayer, PINFO_TRADE_POKEMON );
	new Int:iPlayerLevel = PlayerGetInfo( iPlayer, PINFO_TRADE_LEVEL );
	new Int:iPlayerPokeNum = PlayerPokemonNum( iPlayer, iPlayerPokemon, iPlayerLevel );
	if ( iPlayerPokemon && iPlayerLevel )
	{
		if ( iPlayerPokeNum > -1 )
		{
			formatex( szTrades[ iPlayerTrades ], charsmax(szTrades[]), "%s (Lvl %d)", PokeToName( iPlayerPokemon ), iPlayerLevel );
			iPlayerTrades++;
		}
		else
			bTradeFailed = true;
	}

	new Int:iPlayerItem = PlayerGetInfo( iPlayer, PINFO_TRADE_ITEM );
	new Int:iPlayerItemAmount = PlayerGetInfo( iPlayer, PINFO_TRADE_ITEMNUM );
	if ( iPlayerItem > -1 && iPlayerItemAmount )
	{
		new Int:iItemAmount;
		PlayerHasItem( iPlayer, iPlayerItem, iItemAmount );
		if ( iItemAmount >= iPlayerItemAmount )
		{
			formatex( szTrades[ iPlayerTrades ], charsmax(szTrades[]), "%s x %d", ItemToName( iPlayerItem ), iPlayerItemAmount );
			iPlayerTrades++;
		}
		else
			bTradeFailed = true;
	}

	new Int:iPlayerMoney = PlayerGetInfo( iPlayer, PINFO_TRADE_MONEY );
	if ( iPlayerMoney )
	{
		if ( PlayerGetMoney( iPlayer ) >= iPlayerMoney )
		{
			formatex( szTrades[ iPlayerTrades ], charsmax(szTrades[]), "$%d", iPlayerMoney );
			iPlayerTrades++;
		}
		else
			bTradeFailed = true;
	}

	new String:szPlayerTrades[ 128 ];
	new Int:iTradeLen;
	if ( iPlayerTrades )
	{
		iTradeLen = formatex( szPlayerTrades, charsmax(szPlayerTrades), "%s traded ", PlayerToName( iPlayer ) );
		for ( new Int:iTradeNum; iTradeNum < iPlayerTrades; iTradeNum++ )
		{
			if ( iTradeNum == iPlayerTrades - 1 )
				iTradeLen += copy( szPlayerTrades[ iTradeLen ], charsmax(szPlayerTrades)-iTradeLen, " and " );
			else if ( iTradeNum > 0 )
				iTradeLen += copy( szPlayerTrades[ iTradeLen ], charsmax(szPlayerTrades)-iTradeLen, ", " );
			iTradeLen += copy( szPlayerTrades[ iTradeLen ], charsmax(szPlayerTrades)-iTradeLen, szTrades[ iTradeNum ] );
		}
		iTradeLen += formatex( szPlayerTrades[ iTradeLen ], charsmax(szPlayerTrades)-iTradeLen, " with %s for ", PlayerToName( iTradePlayer ) );
	}
	else
	{
		iTradeLen = formatex( szPlayerTrades, charsmax(szPlayerTrades), "%s gave %s ", PlayerToName( iTradePlayer ), PlayerToName( iPlayer ) );
	}

	iPlayerTrades = 0;

	new Int:iTradePokemon = PlayerGetInfo( iTradePlayer, PINFO_TRADE_POKEMON );
	new Int:iTradeLevel = PlayerGetInfo( iTradePlayer, PINFO_TRADE_LEVEL );
	new Int:iTradePokeNum = PlayerPokemonNum( iTradePlayer, iTradePokemon, iTradeLevel );
	if ( iTradePokemon && iTradeLevel )
	{
		if ( iTradePokeNum > -1 )
		{
			formatex( szTrades[ iPlayerTrades ], charsmax(szTrades[]), "%s (Lvl %d)", PokeToName( iTradePokemon ), iTradeLevel );
			iPlayerTrades++;
		}
		else
			bTradeFailed = true;
	}

	new Int:iTradeItem = PlayerGetInfo( iTradePlayer, PINFO_TRADE_ITEM );
	new Int:iTradeItemAmount = PlayerGetInfo( iTradePlayer, PINFO_TRADE_ITEMNUM );
	if ( iTradeItem > -1 && iTradeItemAmount )
	{
		new Int:iItemAmount;
		PlayerHasItem( iTradePlayer, iTradeItem, iItemAmount );
		if ( iItemAmount >= iTradeItemAmount )
		{
			formatex( szTrades[ iPlayerTrades ], charsmax(szTrades[]), "%s x %d", ItemToName( iTradeItem ), iTradeItemAmount );
			iPlayerTrades++;
		}
		else
			bTradeFailed = true;
	}

	new Int:iTradeMoney = PlayerGetInfo( iTradePlayer, PINFO_TRADE_MONEY );
	if ( iTradeMoney )
	{
		if ( PlayerGetMoney( iTradePlayer ) >= iTradeMoney )
		{
			formatex( szTrades[ iPlayerTrades ], charsmax(szTrades[]), "$%d", iTradeMoney );
			iPlayerTrades++;
		}
		else
			bTradeFailed = true;
	}

	if ( iPlayerTrades )
	{
		for ( new Int:iTradeNum; iTradeNum < iPlayerTrades; iTradeNum++ )
		{
			if ( iTradeNum == iPlayerTrades - 1 )
				iTradeLen += copy( szPlayerTrades[ iTradeLen ], charsmax(szPlayerTrades)-iTradeLen, " and " );
			else if ( iTradeNum > 0 )
				iTradeLen += copy( szPlayerTrades[ iTradeLen ], charsmax(szPlayerTrades)-iTradeLen, ", " );
			iTradeLen += copy( szPlayerTrades[ iTradeLen ], charsmax(szPlayerTrades)-iTradeLen, szTrades[ iTradeNum ] );
		}
	}
	else
	{
		iTradeLen += copy( szPlayerTrades[ iTradeLen ], charsmax(szPlayerTrades)-iTradeLen, "nothing." );
	}

	if ( ( iPlayerPokemon || iTradePokemon ) && ( iPlayerPokeNum == -1 || iTradePokeNum == -1 ) )
	{
		bTradeFailed = true;
	}

	if ( bTradeFailed )
	{
		client_print( iPlayer, print_chat, "[PokeMod] The trade failed." );
		client_print( iTradePlayer, print_chat, "[PokeMod] The trade failed." );
	}
	else
	{
		new String:szAuthID[ 35 ], String:szTraderAuthID[ 35 ];
		get_user_authid( iPlayer, szAuthID, charsmax(szAuthID) );
		get_user_authid( iTradePlayer, szTraderAuthID, charsmax(szTraderAuthID) );
		log_amx( "PokeMod: ^"%s<%s><>^" and ^"%s<%s><>^" %s",
			PlayerToName( iPlayer ), szAuthID, PlayerToName( iTradePlayer ), szTraderAuthID, szPlayerTrades );

		if ( iPlayerPokemon || iTradePokemon )
		{
			PokemonTransfer( .player1 = iPlayer, .pokeNum1 = iPlayerPokeNum, 
							.player2 = iTradePlayer, .pokeNum2 = iTradePokeNum
							);
		}

		if ( iPlayerItem > -1 || iTradeItem > -1 )
		{
			if ( iPlayerItem == iTradeItem )
			{
				PlayerGiveItem( iPlayer, iPlayerItem, iTradeItemAmount - iPlayerItemAmount );
				PlayerGiveItem( iTradePlayer, iPlayerItem, iPlayerItemAmount - iTradeItemAmount );
			}
			else
			{
				PlayerGiveItem( iPlayer, iPlayerItem, -iPlayerItemAmount );
				PlayerGiveItem( iTradePlayer, iPlayerItem, iPlayerItemAmount );

				PlayerGiveItem( iTradePlayer, iTradeItem, -iTradeItemAmount );
				PlayerGiveItem( iPlayer, iTradeItem, iTradeItemAmount );
			}
		}

		if ( iTradeMoney || iPlayerMoney )
		{
			PlayerGiveMoney( iPlayer, iTradeMoney - iPlayerMoney );
			PlayerGiveMoney( iTradePlayer, iPlayerMoney - iTradeMoney );
		}

		client_print( 0, print_chat, "[PokeMod] %s", szPlayerTrades );
	}

	pokemod_funcend_debug( "TradeComplete" );
}


